section	.bss
teststr	resb	32
mystr	resb	42
buf	resq	1

section	.text
global	_start
_start:
	;; setup test string
	mov	byte [teststr+0],'T'
	mov	byte [teststr+1],'e'
	mov	byte [teststr+2],'s'
	mov	byte [teststr+3],'t'
	mov	byte [teststr+4],'S'
	mov	byte [teststr+5],'T'
	mov	byte [teststr+6],'r'
	
	;; read string in
	mov	rax,mystr
	call	getstr

	;; print it out for debugging
	mov	rax,1
	mov	rdi,1
	mov	rsi,mystr
	mov	rdx,42
	syscall
	
	;; check if its equal to test string
	mov	rcx,teststr
	mov	rdx,mystr
	call	strcmp
	
	;; exit with return code
	mov	rdi,rax
	mov	rax,60
	syscall

getstr:
	mov	rbx,rax
.loop:
	call 	getchar
	cmp	rax, -1		; check for terminator
	je	.done

	mov	byte [rbx],al
	add	rbx, 1		; number of chars read
	jmp	.loop

.done:
	mov 	byte [rbx], 0	; write null byte at end
	ret

getchar:
        mov     rax,0x00
        mov     rdi,0           ;stdin fd
        lea     rsi,[buf]
        mov     rdx,1           ;count
        syscall

        cmp     rax,1
        jne     .getchar_fail

        mov     rax,0
        mov     al,[buf]
        ret

.getchar_fail:
        mov     rax,-1
        ret

putchar:
        mov     [buf],al

        mov     rax,0x01
        mov     rdi,1           ;stdout fd
        lea     rsi,[buf]
        mov     rdx,1
        syscall

        ret

strcmp:
	;; inputs
	;; - rcx: pointer to string 1
	;; - rdx: pointer to string 2

	;; outputs
	;; - rax: 0 if equal, 1 if different
	
.loop:
	mov	al,[rcx]
	mov	bl,[rdx]
	
	;; if they are both zero, return equal
	;; if one of them is zero, return not equal
	;; otherwise compare the chars and continue
	
	cmp	al,0
	je	.al.eq
	;; al != 0
	cmp	bl,0
	je	.bl.eq.2
	;; al != 0, bl != 0
	
	cmp	al,bl
	jne	.bl.eq.2
	
	inc	rcx
	inc	rdx
	
	jmp	.loop

.al.eq:
	;; al == 0
	cmp	bl,0
	je	.bl.eq.1
	;; al == 0, bl != 0
	mov	rax, 1
	ret

.bl.eq.1:
	;; al == 0, bl == 0
	mov	rax, 0
	ret

.bl.eq.2:
	;; al != 0, bl == 0
	;; (or) al != bl
	mov	rax, 1
	ret
